package own.stu.jobgib.playown.juc.disruptor;

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.EventTranslator;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.util.DaemonThreadFactory;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.nio.ByteBuffer;

public class Demot
{
    public static void main(String[] args) throws InterruptedException
    {
        int size = 1024;
        //Disruptor<LongEvent> disruptor = new Disruptor<>(new LongEventFactory(), size, DaemonThreadFactory.INSTANCE);

        /**
         * final EventFactory<T> eventFactory,
         * final int ringBufferSize,
         * final ThreadFactory threadFactory,
         * final ProducerType producerType,
         * final WaitStrategy waitStrategy
         */
        Disruptor<LongEvent> disruptor = new Disruptor<>(
                new LongEventFactory(), size, DaemonThreadFactory.INSTANCE, ProducerType.SINGLE, new BlockingWaitStrategy());

        LongEventHandler h1 = new LongEventHandler("h1");
        LongEventHandler h2 = new LongEventHandler("h2");
        LongEventHandler h3 = new LongEventHandler("h3");
        disruptor.handleEventsWith(h1, h2);
        disruptor.after(h1).handleEventsWith(h3);
        disruptor.start();

        RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();
        ByteBuffer bb = ByteBuffer.allocate(8);

        for (int i = 0; i < 5; i++)
        {
            bb.putLong(0, i);
            ringBuffer.publishEvent(((event, sequence) ->
            {
                event.setValue(bb.getLong(0));
            }));
            Thread.sleep(100);
        }

        disruptor.shutdown();
    }

    @Data
    public static class LongEvent
    {
        private long value;
    }

    public static class LongEventFactory implements EventFactory<LongEvent>
    {

        @Override
        public LongEvent newInstance()
        {
            return new LongEvent();
        }
    }

    @Data
    @AllArgsConstructor
    public static class LongEventHandler implements EventHandler<LongEvent>
    {

        private String name;

        @Override
        public void onEvent(LongEvent event, long sequence, boolean endOfBatch) throws Exception
        {
            System.out.println("name: " + name + " => Event: " + event);
        }
    }

    public static class LongEventTranslator implements EventTranslator<LongEvent>
    {

        @Override
        public void translateTo(LongEvent event, long sequence)
        {

        }
    }
}
